package swing;

import model.Entity;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by nuno-rafael-figueiredo on 09-03-2014.
 */
public class EntityTable<TKey, TItem> extends JScrollPane {
    private final List<String> columnNames = new ArrayList<>();
    private final List<Method> methods = new ArrayList<>();
    private final JTable table;

    private Entity<TKey, TItem> entity;

    public EntityTable(Entity<TKey, TItem> entity) {
        this.entity = entity;
        table = new JTable();
        setViewportView(table);

        for (Method method : entity.getItemClass().getMethods()) {
            if (method.getDeclaringClass() == Object.class)
                continue;

            if (method.getReturnType() == Void.TYPE)
                continue;

            if (method.getParameterTypes().length > 0)
                continue;

            if (method.getName().substring(0, 3).equals("get")) {
                columnNames.add(method.getName().substring(3));
                methods.add(method);
            }

            if (method.getName().substring(0, 2).equals("is")) {
                columnNames.add(method.getName().substring(2));
                methods.add(method);
            }
        }
        table.setModel(new TableModel());
    }

    public void setEntity(Entity<TKey, TItem> entity) {
        this.entity = entity;
        table.setModel(new TableModel());
    }

    private class TableModel extends AbstractTableModel {
        public TableModel() {
        }

        @Override
        public int getRowCount() {
            return entity.size();
        }

        @Override
        public int getColumnCount() {
            return methods.size();
        }

        @Override
        public String getColumnName(int column) {
            return columnNames.get(column);
        }

        @Override
        public Object getValueAt(int row, int column) {
            try {
                return methods.get(column).invoke(entity.getArray()[row]);
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        }
    }

}
